package com.example.student.controller;

import com.baomidou.mybatisplus.core.toolkit.StringUtils;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.example.student.generated.entity.Course;
import com.example.student.generated.entity.Student;
import com.example.student.generated.entity.StudentCourse;
import com.example.student.generated.service.IStudentCourseService;
import com.example.student.service.MyCourseService;
import com.example.student.service.MyStudentService;
import com.exmaple.result.PageReq;
import com.exmaple.result.PageReqUnderCondition;
import com.exmaple.result.PageRes;
import com.exmaple.result.Result;
import kotlin.ResultKt;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.*;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import static com.exmaple.result.ErrorCode.USER_ERROR_A0201;
import static com.exmaple.result.ErrorCode.USER_ERROR_A1001;

@Slf4j
@RestController
@RequestMapping(value = "/studentCourse")
public class StudentCourseController {
    @Resource
    private IStudentCourseService studentCourseService ;

    @Resource
    private MyStudentService myStudentService;

    @Resource
    private MyCourseService myCourseService;


    /**
     * 判断该选课记录是否合法
     * @param studentCourse
     * @return
     */
    private boolean isPost(StudentCourse studentCourse)
    {
        //1.学生id存在表学生中
        if(myStudentService.getById(studentCourse.getStuId())==null)
            return false;
        //2.课程id存在表课程中
        if(myCourseService.getById(studentCourse.getCourseId())==null)
            return false;
        //3.id唯一
        if(!studentCourseService.lambdaQuery().eq(StudentCourse::getId,studentCourse.getId()).list().isEmpty())
            return false;
        //4.排除重复选课情况(学生id和课程id一一对应)
        if(!studentCourseService.lambdaQuery()
            .eq(StudentCourse::getCourseId,studentCourse.getCourseId())
            .eq(StudentCourse::getStuId,studentCourse.getStuId()).list().isEmpty()
        )
            return false;
        //5.选课人数超过上限
        int currentStuNum=studentCourseService.lambdaQuery().eq(StudentCourse::getCourseId,studentCourse.getCourseId()).list().size();
        int maxStuNum=myCourseService.getById(studentCourse.getCourseId()).getStuNum();
        return currentStuNum < maxStuNum;
    }
    /**
     * 根据 id 获得单个选课记录
     * @param id
     * @return
     */
    @GetMapping("/{id}")
    public Result<StudentCourse> getId(@PathVariable Long id)
    {
        StudentCourse studentCourse = studentCourseService.getById(id);
        return studentCourse==null? Result.error(USER_ERROR_A1001): Result.success(studentCourse);
    }

    /**
     * 根据 学生id 查找选课记录
     * @param stu_id
     * @return 选课记录
     */
    @GetMapping("/some")
    public Result<List<StudentCourse>> getSome(@RequestParam Long stu_id)
    {
        List<StudentCourse> studentCourseList = studentCourseService.lambdaQuery().eq(StudentCourse::getStuId, stu_id).list();
        return studentCourseList.isEmpty()?Result.error(USER_ERROR_A1001): Result.success(studentCourseList);
    }

    /**
     * 获取所有选课记录
     * @return 所有选课记录
     */
    @GetMapping("/all")
    public Result<List<StudentCourse>> getAll()
    {
        List<StudentCourse> studentCourseList = studentCourseService.list();
        return studentCourseList.isEmpty()?Result.error(USER_ERROR_A1001): Result.success(studentCourseList);
    }

    /**
     * 根据 学生id 分页查询选课记录
     * @param pageNum
     * @param pageSize
     * @param stu_id 学生id，可选填，若不填则默认查询所有
     * @return
     */
    @GetMapping("/page")
    public PageRes<StudentCourse> getPage(@RequestParam Integer pageNum, @RequestParam Integer pageSize, @RequestParam(required = false) Long stu_id)
    {
        /*
mybatis-plus分页插件自带对于pageNum的检错，默认为1L，只有在pageNum大于1的时候才能改变pageNum的值；
        if (pageNum <0||pageSize<=0)
            return null;
        else if (stu_id!=null)
            return this.studentCourseService.lambdaQuery().eq(StudentCourse::getStuId,stu_id).page(new Page<>(pageNum,pageSize)).getRecords();
        return this.studentCourseService.lambdaQuery().page(new Page<>(pageNum,pageSize)).getRecords();
*/
        List<StudentCourse> studentCourseList= new ArrayList<>();
        //无条件分页查询
        if (stu_id==null)
        {
            PageReq pageReq=new PageReq();
            pageReq.setPageNum(pageNum);
            pageReq.setPageSize(pageSize);
            Page<StudentCourse> studentCoursePage = new Page<>(pageReq.getPageNum(), pageReq.getPageSize());
            studentCourseList = studentCourseService.page(studentCoursePage).getRecords();
        }
        //根据学生id 分页查询选课记录
        else
        {
            PageReqUnderCondition pageReq=new PageReqUnderCondition();
            pageReq.setPageNum(pageNum);
            pageReq.setPageSize(pageSize);
            pageReq.setCondition1(stu_id+"");
            Page<StudentCourse> studentPage = new Page<>(pageReq.getPageNum(), pageReq.getPageSize());
            studentCourseList = studentCourseService.lambdaQuery()
                    .eq(StudentCourse::getStuId,Long.parseLong(pageReq.getCondition1()))
                    .page(studentPage)
                    .getRecords();
        }
        return studentCourseList.isEmpty()? PageRes.error(USER_ERROR_A0201):PageRes.success(Integer.toUnsignedLong(studentCourseList.size()),studentCourseList);
    }

    /**
     * 根据学生姓名查询所选的课程信息（学生）
     * @param name
     * @return
     */
    @GetMapping("/student")
    public Result<Map<String,List<Course>>> getByStudentName(@RequestParam String name)
    {
        List<Student> students=myStudentService.lambdaQuery().like(StringUtils.isNotBlank(name),Student::getStuName,name).list();
        if(students.isEmpty())
            return Result.error(USER_ERROR_A0201);
        Map<String,List<Course>> result=new HashMap<String,List<Course>>() {};
        for (Student student : students) {
            List<StudentCourse> studentCourseList = studentCourseService.lambdaQuery().eq(StudentCourse::getStuId, student.getId()).list();
            List<Course> courseList=new ArrayList<>();
            for (StudentCourse studentCourse : studentCourseList) {
                courseList.add(myCourseService.getById(studentCourse.getCourseId()));
            }
            result.put(student.getStuName(),courseList);
        }
        return Result.success(result);
    }

    /**
     * 根据课程名称查询选课学生的信息（老师）
     * @param name
     * @return
     */
    @GetMapping("/course")
    public Result<Map<String,List<Student>>> getByCourseName(@RequestParam String name)
    {
        List<Course> courses=myCourseService.lambdaQuery().like(StringUtils.isNotBlank(name),Course::getCourseName,name).list();
        if(courses.isEmpty())
            return Result.error(USER_ERROR_A0201);
        Map<String,List<Student>> result=new HashMap<String,List<Student>>() {};
        for (Course course : courses) {
            List<StudentCourse> studentCourseList = studentCourseService.lambdaQuery().eq(StudentCourse::getCourseId, course.getId()).list();
            List<Student> studentList=new ArrayList<>();
            for (StudentCourse studentCourse : studentCourseList) {
                studentList.add(myStudentService.getById(studentCourse.getStuId()));
            }
            result.put(course.getCourseName(),studentList);
        }
        return Result.success(result);
    }

    /**
     * 学生id存在时 添加选课记录
     * @param studentCourse
     * @return (success)添加成功 ， (failure)添加失败
     */
    @PostMapping("/one")
    public Result postOne(@RequestBody StudentCourse studentCourse)
    {
        if(isPost(studentCourse))
        {
            studentCourseService.save(studentCourse);
            return Result.error(USER_ERROR_A0201);
        }
        else
            return Result.success();
    }

    /**
     * 学生id及课程id存在时 批量添加选课记录
     * @param studentCourses
     * @return (success)空字符串 ， (failure)添加成功的学生id
     */
    @PostMapping("/batch")
    public Result<String> postBatch(@RequestBody List<StudentCourse> studentCourses)
    {
        StringBuilder res=new StringBuilder();
        for (StudentCourse studentCourse : studentCourses) {
            if(isPost(studentCourse))
            {
                studentCourseService.save(studentCourse);
                res.append(studentCourse.getId());
                res.append(" ");
            }
        }
        return res.length()==0?Result.error(USER_ERROR_A0201):Result.success(res.toString());
    }

    /**
     * 根据id修改单个成绩
     * @param studentCourse
     * @return (success)修改成功 ， (failure)修改失败
     */
    @PutMapping("/one")
    public Result putOne(StudentCourse studentCourse)
    {
        return studentCourseService.lambdaUpdate().eq(StudentCourse::getId,studentCourse.getId()).update(studentCourse)?Result.success():Result.error(USER_ERROR_A0201);
    }

    /**
     * 根据id修改多个成绩
     * @param studentCourses
     * @return (success)空字符串 ， (failure)修改成功的id
     */
    @PutMapping("/batch")
    public Result<String> putBatch(List<StudentCourse> studentCourses)
    {
        StringBuilder res=new StringBuilder();
        for (StudentCourse studentCourse : studentCourses) {
            res.append(studentCourseService.lambdaUpdate().eq(StudentCourse::getId,studentCourse.getId()).update(studentCourse)?studentCourse.getId():"");
        }
        return res.length()==0?Result.error(USER_ERROR_A0201):Result.success(res.toString());
    }

    @DeleteMapping("/{id}")
    public Result deleteId(@PathVariable Long id)
    {
        return studentCourseService.removeById(id)?Result.success():Result.error(USER_ERROR_A0201);
    }

    @DeleteMapping("/batch")
    public Result<String> deleteBatch(@RequestBody List<StudentCourse> studentCourses)
    {
        StringBuilder res=new StringBuilder();
        for (StudentCourse studentCourse : studentCourses) {
            if (studentCourseService.removeById(studentCourse.getId()))
            {
                res.append(studentCourse.getId()).append(" ");
            }
        }
        return res.length()==0?Result.error(USER_ERROR_A0201):Result.success(res.toString());
    }

}
